package com.ease.component.controls {

   import com.ease.component.constant.IconConstant;
   import com.ease.component.events.TabNavigationEvent;

   import flash.events.MouseEvent;

   import mx.controls.ButtonLabelPlacement;
   import mx.controls.Image;
   import mx.controls.tabBarClasses.Tab;
   import mx.core.EdgeMetrics;
   import mx.core.IBorder;
   import mx.core.IFlexAsset;
   import mx.core.mx_internal;

   use namespace mx_internal;

   [Event(name = "closeTab")]
   /**
    * Tab button that supports close icon.
    */
   public class TabButton extends Tab {

      private var _closeIcon:Image;
      private var _hasCloseIcon:Boolean;

      /**
       * The actual index of the tab.
       */
      public var index:Number;

      /**
       * Constructor for a TabButton
       * @param label
       *    the tab label
       * @param hasCloseIcon
       *    if the tab can be closed
       * @param icon
       *    an icon for the tab
       */
      public function TabButton(label:String = "", hasCloseIcon:Boolean = true, icon:Class = null) {
         super();
         mouseChildren = true;
         _hasCloseIcon = hasCloseIcon;
         this.label = label;
         autoRepeat = false;
      }

      /**
       * Property controlling if the tab can be closed by the user.
       */
      public function set hasCloseIcon(value:Boolean):void {
         _hasCloseIcon = value;
         if (_hasCloseIcon) {
            _closeIcon.visible = true;
         } else {
            _closeIcon.visible = false;
         }
      }

      public function get hasCloseIcon():Boolean {
         return _hasCloseIcon;
      }

      /**
       * @private
       * Override create children function to create the close button.
       */
      override protected function createChildren():void {
         super.createChildren();
         if (!_closeIcon) {
            _closeIcon = new Image();
            _closeIcon.id = "closeIcon";
            _closeIcon.source = IconConstant.CLOSE_TAB;
            _closeIcon.visible = _hasCloseIcon;
            _closeIcon.addEventListener(MouseEvent.MOUSE_DOWN, function(event:MouseEvent):void {
                 event.stopImmediatePropagation();
                 dispatchEvent(new TabNavigationEvent(TabNavigationEvent.CLOSE_TAB, index, true));
            });
            addChild(_closeIcon);
         }
      }

      /**
       * @private
       * Override measure function to properly calculate widths if
       * there is a close icon.
       */
      override protected function measure():void {
         super.measure();
         if (_hasCloseIcon) {
            measuredMinWidth = _closeIcon.getExplicitOrMeasuredWidth() +
               getStyle("paddingLeft") + getStyle("paddingRight");
            measuredWidth += _closeIcon.getExplicitOrMeasuredWidth() + getStyle("horizontalGap");

            if (currentSkin &&
                currentSkin is IBorder && !(currentSkin is IFlexAsset)) {
               var bm:EdgeMetrics = IBorder(currentSkin).borderMetrics;
               measuredMinWidth += bm.left + bm.right;
            }

            measuredWidth = Math.floor(measuredWidth);
            measuredMinWidth = Math.floor(measuredMinWidth);
         }

         measuredWidth = Math.min(maxWidth, measuredWidth);
      }

      /**
       * @private
       * Override update display list to position the close icon.
       *
       * @param unscaledWidth
       * @param unscaledHeight
       */
      override protected function updateDisplayList(unscaledWidth:Number,
                                                    unscaledHeight:Number):void {
         super.updateDisplayList(unscaledWidth, unscaledHeight);

         if (_hasCloseIcon) {
            var leftEdge:Number = getStyle("paddingLeft");
            var rightEdge:Number = unscaledWidth - getStyle("paddingRight");
            var topEdge:Number = getStyle("paddingTop");
            var bottomEdge:Number = unscaledHeight - getStyle("paddingBottom");
            var bm:EdgeMetrics = currentSkin &&
                                 currentSkin is IBorder && !(currentSkin is IFlexAsset) ?
                                 IBorder(currentSkin).borderMetrics :
                                 null;
            if (bm) {
               leftEdge += bm.left;
               rightEdge -= bm.right;
               topEdge += bm.top;
               bottomEdge -= bm.bottom;
            }

            _closeIcon.move(
               rightEdge - _closeIcon.getExplicitOrMeasuredWidth(),
               topEdge + (bottomEdge - topEdge - _closeIcon.getExplicitOrMeasuredHeight()) / 2);
            _closeIcon.setActualSize(
               _closeIcon.getExplicitOrMeasuredWidth(),
               _closeIcon.getExplicitOrMeasuredHeight());
            setChildIndex(_closeIcon, numChildren - 1);
            rightEdge -= _closeIcon.getExplicitOrMeasuredWidth();

            if (label) {
               rightEdge -= getStyle("horizontalGap");

               if (currentIcon) {
                  if (labelPlacement == ButtonLabelPlacement.LEFT) {
                     leftEdge = currentIcon.x + currentIcon.width +
                        getStyle("horizontalGap");
                  } else if (labelPlacement == ButtonLabelPlacement.RIGHT) {
                     currentIcon.x = rightEdge - currentIcon.width;
                     rightEdge -= currentIcon.width + getStyle("horizontalGap");
                  }
               }

               textField.x = leftEdge;
               textField.width = Math.max(rightEdge - leftEdge, 0);
               textField.truncateToFit();
            }
         }
         if (selected) {
            textField.y --;
            if (currentIcon) {
               currentIcon.y --;
            }
         }
      }

      /**
       * Getter function for the close icon
       * @return
       *    The close icon
       */
      public function get closeIcon():Image {
         return _closeIcon;
      }
   }
}
